import React, { useEffect, useRef } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls, Grid, Text } from '@react-three/drei';
import * as THREE from 'three';
import StorageSlot from './StorageSlot';

// 创建文字标签 - 参考xyz项目实现
function createTextSprite(text, color = '#ffffff', fontSize = 40) {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  context.font = `${fontSize}px Arial`;
  
  // 测量文本尺寸
  const textWidth = context.measureText(text).width;
  canvas.width = textWidth + 10;
  canvas.height = fontSize + 10;
  
  // 重新设置字体（因为改变了canvas尺寸）
  context.font = `${fontSize}px Arial`;
  context.fillStyle = 'rgba(0, 0, 0, 0.7)'; // 半透明黑色背景
  context.fillRect(0, 0, canvas.width, canvas.height);
  
  context.fillStyle = color;
  context.textAlign = 'center';
  context.textBaseline = 'middle';
  context.fillText(text, canvas.width / 2, canvas.height / 2);
  
  // 创建纹理和材质
  const texture = new THREE.CanvasTexture(canvas);
  const material = new THREE.SpriteMaterial({ map: texture });
  const sprite = new THREE.Sprite(material);
  
  // 设置精灵大小
  const scaleX = canvas.width / 100;
  const scaleY = canvas.height / 100;
  sprite.scale.set(scaleX, scaleY, 1);
  
  return sprite;
}

// 坐标轴组件 - 参考xyz项目实现
function Axes({ warehouseSize = { rows: 4, columns: 8, layers: 4 } }) {
  const axesRef = useRef();
  const labelRefs = useRef({});
  
  useEffect(() => {
    if (axesRef.current) {
      // 清理之前的坐标轴
      while (axesRef.current.children.length > 0) {
        const child = axesRef.current.children[0];
        axesRef.current.remove(child);
        if (child.geometry) child.geometry.dispose();
        if (child.material) {
          if (child.material.map) child.material.map.dispose();
          child.material.dispose();
        }
      }
      
      // 计算合适的坐标轴尺寸，基于仓库尺寸
      // 考虑仓库是分左右两侧的，所以X轴需要更长一些
      const xLength = warehouseSize.columns / 2 + 2; // 增加X轴长度
      const yLength = warehouseSize.layers + 1;
      const zLength = warehouseSize.rows / 2 + 4; // 前后各留空间
      
      // 使用自定义方法创建三个不同长度的坐标轴
      const xGeometry = new THREE.BufferGeometry().setFromPoints([
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(xLength, 0, 0)
      ]);
      const yGeometry = new THREE.BufferGeometry().setFromPoints([
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(0, yLength, 0)
      ]);
      const zGeometry = new THREE.BufferGeometry().setFromPoints([
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(0, 0, zLength)
      ]);
      
      // 创建坐标轴材质
      const xMaterial = new THREE.LineBasicMaterial({ color: 0xff0000, linewidth: 2 });
      const yMaterial = new THREE.LineBasicMaterial({ color: 0x00ff00, linewidth: 2 });
      const zMaterial = new THREE.LineBasicMaterial({ color: 0x0000ff, linewidth: 2 });
      
      // 创建坐标轴线
      const xAxis = new THREE.Line(xGeometry, xMaterial);
      const yAxis = new THREE.Line(yGeometry, yMaterial);
      const zAxis = new THREE.Line(zGeometry, zMaterial);
      
      axesRef.current.add(xAxis);
      axesRef.current.add(yAxis);
      axesRef.current.add(zAxis);
      
      // 添加扁平箭头
      const arrowSize = Math.max(0.3, Math.min(xLength, yLength, zLength) * 0.1);
      
      // X轴扁平箭头
      const xArrowGeometry = new THREE.BufferGeometry().setFromPoints([
        new THREE.Vector3(xLength, -arrowSize*0.5, 0),
        new THREE.Vector3(xLength + arrowSize * 0.5, 0, 0),
        new THREE.Vector3(xLength, arrowSize*0.5, 0)
      ]);
      const xArrow = new THREE.Line(xArrowGeometry, xMaterial);
      
      // Y轴扁平箭头
      const yArrowGeometry = new THREE.BufferGeometry().setFromPoints([
        new THREE.Vector3(-arrowSize*0.5, yLength, 0),
        new THREE.Vector3(0, yLength + arrowSize * 0.5, 0),
        new THREE.Vector3(arrowSize*0.5, yLength, 0)
      ]);
      const yArrow = new THREE.Line(yArrowGeometry, yMaterial);
      
      // Z轴扁平箭头
      const zArrowGeometry = new THREE.BufferGeometry().setFromPoints([
        new THREE.Vector3(0, -arrowSize*0.5, zLength),
        new THREE.Vector3(0, 0, zLength + arrowSize * 0.5),
        new THREE.Vector3(0, arrowSize*0.5, zLength)
      ]);
      const zArrow = new THREE.Line(zArrowGeometry, zMaterial);
      
      axesRef.current.add(xArrow);
      axesRef.current.add(yArrow);
      axesRef.current.add(zArrow);
      
      // 创建坐标轴标签，使用合适的字体大小
      const fontSize = Math.max(20, Math.min(40, Math.max(xLength, yLength, zLength) * 3));
      
      const xLabel = createTextSprite('X (列)', '#ff0000', fontSize);
      xLabel.position.set(xLength + 0.5, 0, 0);
      axesRef.current.add(xLabel);
      labelRefs.current.x = xLabel;
      
      const yLabel = createTextSprite('Y (层)', '#00ff00', fontSize);
      yLabel.position.set(0, yLength + 0.5, 0);
      axesRef.current.add(yLabel);
      labelRefs.current.y = yLabel;
      
      const zLabel = createTextSprite('Z (排)', '#0000ff', fontSize);
      zLabel.position.set(0, 0, zLength + 0.5);
      axesRef.current.add(zLabel);
      labelRefs.current.z = zLabel;
      
      // 清理函数
      return () => {
        if (axesRef.current) {
          // 清理所有子对象
          while (axesRef.current.children.length > 0) {
            const child = axesRef.current.children[0];
            axesRef.current.remove(child);
            if (child.geometry) child.geometry.dispose();
            if (child.material) {
              if (child.material.map) child.material.map.dispose();
              child.material.dispose();
            }
          }
        }
      };
    }
  }, [warehouseSize]);
  
  return <group ref={axesRef} />;
}

// 3D仓库场景组件
function WarehouseScene({ warehouseData, onSlotClick, selectedSlot }) {
  const { rows, columns, layers, slots } = warehouseData;
  const gapBetweenSides = 3; // 中间通道宽度
  const rowsPerSide = rows / 2;
  
  // 创建仓库尺寸对象，供坐标轴组件使用
  const warehouseSize = { rows, columns, layers };

  // 计算货位在3D空间中的位置 (转换1基索引到0基索引用于3D定位)
  const getSlotPosition = (layerIdx, rowIdx, colIdx) => {
    // 确定排在哪一侧（row现在是排，沿Z轴方向）
    const isLeftSide = rowIdx <= rowsPerSide;
    const sideOffset = isLeftSide ? 
      -(gapBetweenSides / 2 + rowsPerSide - 0.5) : 
      (gapBetweenSides / 2 + rowsPerSide - 0.5);
    
    // X轴位置 (列，从左到右) (转换1基索引到0基索引)
    const x = -(columns / 2) + (colIdx - 1);
    
    // Y轴位置（层）(转换1基索引到0基索引)
    const y = layerIdx - 1;
    
    // Z轴位置（排，前后方向）(转换1基索引到0基索引)
    const z = sideOffset + (isLeftSide ? rowIdx - 1 : rowIdx - rowsPerSide - 1);
    
    return [x, y, z];
  };

  return (
    <>
      {/* Lighting */}
      <ambientLight intensity={0.3} />
      <directionalLight position={[0, 10, 0]} intensity={0.8} castShadow />
      <directionalLight position={[10, 10, 5]} intensity={1} castShadow />
      <directionalLight position={[-10, -10, -5]} intensity={0.3} />
      <pointLight position={[0, 10, 0]} intensity={0.5} />

      {/* Grid floor - Expanded range */}
      <Grid
        args={[30, columns * 2]}
        cellSize={1}
        cellThickness={0.5}
        cellColor="#6f6f6f"
        sectionSize={5}
        sectionThickness={1}
        sectionColor="#9d4b4b"
        fadeDistance={50}
        fadeStrength={1}
        position={[0, -0.5, 0]}
        raycast={() => null}
      />

      {/* Generate slots - Left/right separated layout */}
      {Array.from({ length: layers }).map((_, layerIdx) =>
        Array.from({ length: rows }).map((_, rowIdx) =>
          Array.from({ length: columns }).map((_, colIdx) => {
            // 计算自然数编号 (保持1基索引)
            const slotNumber = layerIdx * rows * columns + rowIdx * columns + colIdx + 1;
            const slotId = `${slotNumber}`;
            const slot = slots[slotId];
            
            // 确保slot存在
            if (!slot) {
              console.warn(`Slot ${slotId} not found`);
              return null;
            }
            
            return (
              <StorageSlot
                key={slotId}
                position={getSlotPosition(layerIdx + 1, rowIdx + 1, colIdx + 1)} // 使用1基索引
                hasGoods={slot.hasGoods}
                slotInfo={slot}
                onClick={() => onSlotClick && onSlotClick(slot.id, slot)}
                isSelected={selectedSlot && String(selectedSlot) === String(slot.id)}
              />
            );
          })
        )
      )}

      {/* 坐标轴 - 使用THREE.AxesHelper */}
      <Axes warehouseSize={warehouseSize} />
      
      {/* Orbit Controls */}
      <OrbitControls 
        makeDefault
        enablePan={true}
        enableZoom={true}
        enableRotate={true}
        minDistance={5}
        maxDistance={50}
        maxPolarAngle={Math.PI / 2}
      />
    </>
  );
}

// 主仓库3D组件
export default function Warehouse3D({ warehouseData, onSlotClick, selectedSlot }) {
  // 处理场景点击空白处（使用onPointerMissed事件）
  const handleScenePointerMissed = () => {
    if (selectedSlot && onSlotClick) {
      onSlotClick(null);
    }
  };

  return (
    <div style={{ width: '100%', height: '100%' }}>
      <Canvas
        camera={{ position: [15, 20, 25], fov: 50 }}
        shadows
        onPointerMissed={handleScenePointerMissed}
      >
        <color attach="background" args={['#1a1a1a']} />
        <WarehouseScene 
          warehouseData={warehouseData} 
          onSlotClick={onSlotClick}
          selectedSlot={selectedSlot}
        />
      </Canvas>
    </div>
  );
}
